<script>
import { defineComponent, reactive, h, ref, toRaw, watch } from 'vue'
// import FlagList from '@Common/FlagList/index'
import * as Antd from 'ant-design-vue'
import { max } from 'lodash'
import DSelect from '@Components/DSelect'

import CheckboxButtonGroup from '@Components/checkboxButtonGroup'

export const MakeFormState = (config) => {
  let _config = {}
  config.map((x) => {
    _config[x.key] = x.initValue

    //统计label，并计算其长度、
    if (x.formItem && x.formItem.label) {
      //在对象中重新加一项
      x.placeholder = x.formItem.label
      var cn =
        x.formItem.label instanceof Array
          ? x.formItem.label[0].match(/[\u4e00-\u9fa5]/g)
          : x.formItem.label.match(/[\u4e00-\u9fa5]/g)
      //var en = x.formItem.label.match(/[\u0000-\u00ff]/g)
      x.formItem.label_length = cn ? cn.length : null
    } else {
      if (x.formItem) {
        x.formItem.label_length = 0
      } else {
        x.formItem = { label_length: 0 }
      }
    }

    return x
  })

  //计算标签宽度，设置统一宽度
  let len = max(config.map((x) => x.formItem.label_length))

  config.map((x) => {
    if (!x.formItem.label) return
    x.formItem.label =
      '　'.repeat(len - x.formItem.label_length) + x.formItem.label
  })

  return _config
}
/**
 * {
 *  key:[
 *    {required:true,message:"XXXXXX"}
 *  ]
 * }
 *
 */
export const makeRule = (_config) => {
  let _rule = {}
  _config.data.map((x) => {
    x.rule && (_rule[x.key] = toRaw(x.rule))
  })
  return _rule
}

export default defineComponent({
  components: {
    'a-form': Antd.Form,
    'a-form-item': Antd.FormItem,
    'a-input': Antd.Input,
    'a-textarea': Antd.Textarea,
    'a-select': Antd.Select,
    'a-col': Antd.Col,
    'a-row': Antd.Row,
    'a-date-picker': Antd.DatePicker,
    // FlagList,
    'a-radion': Antd.Radio,
    'a-radio-group': Antd.RadioGroup,
    'a-space': Antd.Space,
    'a-button': Antd.Button,
    'a-range-picker': Antd.RangePicker,
    'a-time-picker': Antd.TimePicker,
    'a-month-picker': Antd.MonthPicker,
    DSelect,
    CheckboxButtonGroup,
  },
  props: {
    formConfig: {
      type: Array,
      required: true,
    },
    value: {
      type: Object,
      required: true,
    },
    enterCallBack: {
      type: Function,
      default: () => {
        return null
      },
    },
  },
  setup(props, context) {
    let form_config = reactive({ data: props.formConfig })

    let form_state = reactive(toRaw(props.value))
    //备份
    let _bak_form_state = { ...toRaw(form_state) }

    let rule = reactive({ data: makeRule(form_config) })

    const {
      resetFields,
      validate,
      validateInfos,
      mergeValidateInfo,
      clearValidate,
    } = Antd.Form.useForm(form_state, rule.data)

    const makeFormItem = (item) => {
      if (item.uiType == 'custom') {
        return item.ui
      }

      if (item.uiType == 'radio') {
        return (
          <Antd.RadioGroup
            options={item.source}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          ></Antd.RadioGroup>
        )
      }
      if (item.uiType == 'checkbox') {
        return (
          <Antd.CheckboxGroup
            options={item.source}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          ></Antd.CheckboxGroup>
        )
      }

      if (item.uiType == 'acheckbox') {
        return (
          <Antd.Checkbox
            checked={form_state[item.key]}
            onChange={(e) => {
              form_state[item.key] = e.target.checked
            }}
            {...item.attr}
          >
            {item.attr?.slots && item.attr.slots()}
          </Antd.Checkbox>
        )
      }

      if (item.uiType == 'dselect') {
        return (
          <DSelect
            options={item.source}
            emptyLable={item.attr.emptyLable || '全部'}
            emptyValue={item.attr.emptyValue}
            uiAttr={{
              placeholder: item.placeholder,
              value: form_state[item.key],
              ...item.attr,
              onKeyup: (e) => {
                if (e.key == 'Enter' && props.enterCallBack) {
                  props.enterCallBack()
                }
              },
            }}
            onChange={(e) => {
              form_state[item.key] = e.value
            }}
          />
        )
      }
      if (item.uiType == 'img') {
        return (
          <div {...item.attr}>
            <Antd.Image src={form_state[item.key]} />
          </div>
        )
      }
      if (item.uiType == 'slider') {
        return (
          <Antd.Row style={{ width: '100%' }} gutter={[10, 10]} align="middle">
            <Antd.Col span={20}>
              <Antd.Slider
                {...item.attr}
                onChange={(e) => {
                  form_state[item.key] = e
                }}
                value={form_state[item.key]}
              />
            </Antd.Col>
            <Antd.Col span={4} style={{ 'text-align': 'right' }}>
              <label style={{ color: '#778899' }}>
                {'延后' + form_state[item.key] + '小时'}
              </label>
            </Antd.Col>
          </Antd.Row>
        )
      }

      if (item.uiType == 'label') {
        return <div {...item.attr}>{item.initValue}</div>
      }
      if (item.uiType == 'input') {
        // console.log(item.directives)
        return (
          <a-input
            onKeyup={(e) => {
              if (e.key == 'Enter' && props.enterCallBack) {
                props.enterCallBack()
              }
            }}
            value={form_state[item.key]}
            placeholder={item.placeholder}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
            // {...{ directives: item.directives }}
          />
        )
      }

      if (item.uiType == 'datePicker') {
        return (
          <a-date-picker
            style="width:100%"
            valueFormat="YYYY-MM-DD"
            format="YYYY-MM-DD"
            placeholder={item.placeholder}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          />
        )
      }
      if (item.uiType == 'monthPicker') {
        return (
          <a-month-picker
            style="width:100%"
            valueFormat="YYYY-MM-DD"
            format="YYYY-MM-DD"
            placeholder={item.placeholder}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          />
        )
      }
      if (item.uiType == 'rangePicker') {
        return (
          <a-range-picker
            style="width:100%"
            valueFormat="YYYY-MM-DD HH:mm:ss"
            format="YYYY-MM-DD HH:mm:ss"
            show-time={{ format: 'HH:mm:ss' }}
            placeholder={item.placeholder}
            value={
              item.key instanceof Array
                ? [form_state[item.key[0]], form_state[item.key[1]]]
                : form_state[item.key]
            }
            onUpdate:value={(e) => {
              if (item.key instanceof Array) {
                form_state[item.key[0]] = e[0]
                form_state[item.key[1]] = e[1]
              } else {
                form_state[item.key] = e
              }
            }}
            {...item.attr}
          />
        )
      }

      if (item.uiType == 'textarea') {
        return (
          <a-textarea
            placeholder={item.placeholder}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          />
        )
      }
      if (item.uiType == 'timePicker') {
        return (
          <a-time-picker
            style={{ width: '100%' }}
            placeholder={item.placeholder}
            value={form_state[item.key]}
            format={'HH:mm:ss'}
            valueFormat="HH:mm:ss"
            onChange={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          />
        )
      }
      if (item.uiType == 'select') {
        return (
          <a-select
            style={{ width: '100%' }}
            options={item.source}
            placeholder={item.placeholder}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
            v-slots={item.attr?.slots || {}}
            onKeyup={(e) => {
              if (e.key == 'Enter' && props.enterCallBack) {
                props.enterCallBack()
              }
            }}
          />
        )
      }
      if (item.uiType == 'checkboxButtonGroup') {
        return (
          <CheckboxButtonGroup
            style={{ width: '100%' }}
            list={item.source}
            placeholder={item.placeholder}
            value={form_state[item.key]}
            onUpdate:value={(e) => {
              form_state[item.key] = e
            }}
            {...item.attr}
          />
        )
      }
      // if (typeof item.uiType == 'object' && item.uiType.name == 'FlagList') {
      //   return (
      //     <FlagList
      //       value={form_state[item.key]}
      //       onUpdate:value={(e) => {
      //         form_state[item.key] = e
      //       }}
      //       {...item.attr}
      //     />
      //   )
      // }
    }

    watch(
      form_state,
      () => {
        context.emit('update:value', toRaw(form_state))
      },
      {
        deep: true,
        immediate: true,
      }
    )
    //重置查询条件。如果传_value则用_value否则用_bak_form_state
    let resetState = (_value = null) => {
      if (_value == null) {
        for (var prop in _bak_form_state) {
          form_state[prop] = _bak_form_state[prop]
        }
      } else {
        for (var props in _value) {
          form_state[props] = _value[props]
        }
      }
    }
    return {
      resetState,
      form_config,
      makeFormItem,
      rule,
      resetFields,
      validate,
      validateInfos,
      mergeValidateInfo,
      clearValidate,
    }
  },
  render() {
    return (
      <a-form hideRequiredMark={true}>
        {
          <a-row gutter={[5, 5]}>
            {this.form_config.data.map((form) => {
              if (form.ignore) return
              return (
                <a-col {...form.col}>
                  <a-form-item
                    {...form.formItem}
                    {...this.validateInfos[form.key]}
                  >
                    {this.makeFormItem(form)}
                  </a-form-item>
                </a-col>
              )
            })}
          </a-row>
        }
      </a-form>
    )
  },
})
</script>
